package com.dnndo.web.controller.system;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dnndo.common.constant.RedisConstant;
import com.dnndo.common.core.domain.AjaxResult;
import com.dnndo.common.core.domain.R;
import com.dnndo.common.core.domain.entity.SysUser;
import com.dnndo.common.core.domain.model.*;
import com.dnndo.common.core.redis.RedisCache;
import com.dnndo.common.utils.SecurityUtils;
import com.dnndo.common.enums.UserStatus;
import com.dnndo.common.utils.MessageUtils;
import com.dnndo.framework.manager.AsyncManager;
import com.dnndo.framework.manager.factory.AsyncFactory;
import com.dnndo.common.constant.Constants;
import com.dnndo.framework.web.service.SysLoginService;
import com.dnndo.framework.web.service.SysPermissionService;
import com.dnndo.framework.web.service.TokenService;
import com.dnndo.system.domain.vo.LoginVO;
import com.dnndo.system.service.IMenuService;
import com.dnndo.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.Set;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private IMenuService menuService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private TokenService tokenService;

    /**
     * 密码登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    //完成 数据源区分
    @PostMapping(path = "/login", consumes = MediaType.APPLICATION_JSON_VALUE)
    public R<LoginVO> loginJson(@RequestBody LoginBody loginBody) {
      return loginInternal(loginBody);
    }

  @PostMapping(path = "/login", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public R<LoginVO> loginForm(@ModelAttribute LoginBody loginBody) {
    return loginInternal(loginBody);
  }

  private R<LoginVO> loginInternal(LoginBody loginBody) {
    System.out.println("登陆的用户名："+loginBody.getUsername()+"登陆的密码："+ loginBody.getPassword());
    String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
    String LoginSchoolName = userService.selectUserByPhone(loginBody.getUsername()).getSchoolName();
    if(LoginSchoolName==null){
      LoginSchoolName = "未绑定学校";
    }
    return R.ok(new LoginVO(token,LoginSchoolName));
  }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    //完成 数据源区分
    @GetMapping("/getInfo")
    public R<SysUser> getInfo()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        return R.ok(user);
    }

    /**
     * 获取权限信息
     */
    @GetMapping("/getPermissions")
    public AjaxResult getPermissions()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        // 权限集合 完成数据源区分
        Set<String> permissions = permissionService.getMenuPermission(user);
        if (!loginUser.getPermissions().equals(permissions))
        {
            loginUser.setPermissions(permissions);
            tokenService.refreshToken(loginUser);
        }
        JSONObject result = new JSONObject();
        result.put("permissions", loginUser.getPermissions());
        return AjaxResult.success(result);
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    //完成 数据源区分
    @GetMapping("/getRouters")
    public AjaxResult getRouters()
    {
        return AjaxResult.success(menuService.getTree());
    }

    /**
     * 忘记密码
     */
    @PostMapping("/forgetPwd")
    public R<?> forgetPwd(@RequestBody ForgetPwdDTO dto) {
        //查询用户是否存在
        long count = userService.count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getPhonenumber, dto.getPhone())
                .eq(SysUser::getDelFlag, 0));
        if (count == 0) {
            return R.fail("用户不存在");
        }
        //验证短信验证码
        Boolean hasKey = redisCache.hasKey(RedisConstant.SMS_CODE_KEY + dto.getPhone());
        if (!hasKey) {
            return R.fail("验证码错误");
        } else {
            String smsCode = redisCache.getCacheObject(RedisConstant.SMS_CODE_KEY + dto.getPhone());
            if (!dto.getSmsCode().equals(smsCode)) {
                return R.fail("验证码错误");
            } else {
                redisCache.deleteObject(RedisConstant.SMS_CODE_KEY + dto.getPhone());
                redisCache.deleteObject(RedisConstant.SMS_CODE_COUNT_KEY + dto.getPhone());
            }
        }
        //修改密码
        boolean b = userService.update(new LambdaUpdateWrapper<SysUser>()
                .eq(SysUser::getPhonenumber, dto.getPhone())
                .set(SysUser::getPassword, SecurityUtils.encryptPassword(dto.getPassword())));
        if (!b) {
            return R.fail("修改失败");
        } else {
            return R.ok();
        }
    }


    /**
     * 手机验证码登录
     */
    @PostMapping("/LoginBySms")
    public R<LoginVO> LoginBySms(@RequestBody SmsLoginDTO dto) {
        //查询用户是否存在
        SysUser user = userService.getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getPhonenumber, dto.getPhone())
                .eq(SysUser::getDelFlag, 0));
        if (user == null) {
            return R.fail("用户不存在");
        }

        //验证短信验证码
        Boolean hasKey = redisCache.hasKey(RedisConstant.SMS_CODE_KEY + dto.getPhone());
        if (!hasKey) {
            return R.fail("验证码错误");
        } else {
            String smsCode = redisCache.getCacheObject(RedisConstant.SMS_CODE_KEY + dto.getPhone());
            if (!dto.getSmsCode().equals(smsCode)) {
                return R.fail("验证码错误");
            } else {
                redisCache.deleteObject(RedisConstant.SMS_CODE_KEY + dto.getPhone());
                redisCache.deleteObject(RedisConstant.SMS_CODE_COUNT_KEY + dto.getPhone());
            }
        }

        // 检查用户状态
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
            return R.fail("用户已被删除");
        }
        if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            return R.fail("用户已被禁用");
        }

                // 确保用户有角色信息
        SysUser userWithRoles = userService.selectUserByUserName(user.getUserName());
        if (userWithRoles == null) {
            return R.fail("用户不存在");
        }

        // 检查用户是否有角色
        if (userWithRoles.getRoles() == null || userWithRoles.getRoles().isEmpty()) {
            return R.fail("用户没有分配角色，请联系管理员");
        }

        // 直接创建登录用户对象，跳过密码验证
        LoginUser loginUser = new LoginUser(userWithRoles.getUserId(), userWithRoles.getDeptId(), userWithRoles, permissionService.getMenuPermission(userWithRoles));

        // 记录登录日志
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginUser.getUserId().toString(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));

        // 记录登录信息
        loginService.recordLoginInfo(loginUser.getUserId());

        // 生成token
        String token = tokenService.createToken(loginUser);

        // 获取学校名称
        String loginSchoolName = user.getSchoolName();
        if (loginSchoolName == null) {
            loginSchoolName = "未绑定学校";
        }

        return R.ok(new LoginVO(token, loginSchoolName));
    }
}
